#include "stdafx.h"
#include "GLUtil.h"


typedef struct PROC_LIST {
	const char *funcname;
	PROC *ppfunc;
} PROC_LIST;

#define ARRAY_SIZE(x)	(sizeof(x) / sizeof((x)[0]))

extern "C" {
PFNGLBINDBUFFERPROC __glewBindBuffer = NULL;
PFNGLBUFFERDATAPROC __glewBufferData = NULL;
PFNGLBUFFERSUBDATAPROC __glewBufferSubData = NULL;
PFNGLDELETEBUFFERSPROC __glewDeleteBuffers = NULL;
PFNGLGENBUFFERSPROC __glewGenBuffers = NULL;
PFNGLGETBUFFERSUBDATAPROC __glewGetBufferSubData = NULL;
PFNGLGETQUERYOBJECTIVPROC __glewGetQueryObjectiv = NULL;
PFNGLISBUFFERPROC __glewIsBuffer = NULL;
PFNGLMAPBUFFERPROC __glewMapBuffer = NULL;
PFNGLUNMAPBUFFERPROC __glewUnmapBuffer = NULL;

PFNGLATTACHSHADERPROC __glewAttachShader = NULL;
PFNGLBINDATTRIBLOCATIONPROC __glewBindAttribLocation = NULL;
PFNGLBLENDEQUATIONSEPARATEPROC __glewBlendEquationSeparate = NULL;
PFNGLCOMPILESHADERPROC __glewCompileShader = NULL;
PFNGLCREATEPROGRAMPROC __glewCreateProgram = NULL;
PFNGLCREATESHADERPROC __glewCreateShader = NULL;
PFNGLDELETEPROGRAMPROC __glewDeleteProgram = NULL;
PFNGLDELETESHADERPROC __glewDeleteShader = NULL;
PFNGLDETACHSHADERPROC __glewDetachShader = NULL;
PFNGLDISABLEVERTEXATTRIBARRAYPROC __glewDisableVertexAttribArray = NULL;
PFNGLDRAWBUFFERSPROC __glewDrawBuffers = NULL;
PFNGLENABLEVERTEXATTRIBARRAYPROC __glewEnableVertexAttribArray = NULL;
PFNGLGETACTIVEATTRIBPROC __glewGetActiveAttrib = NULL;
PFNGLGETACTIVEUNIFORMPROC __glewGetActiveUniform = NULL;
PFNGLGETATTACHEDSHADERSPROC __glewGetAttachedShaders = NULL;
PFNGLGETATTRIBLOCATIONPROC __glewGetAttribLocation = NULL;
PFNGLGETPROGRAMINFOLOGPROC __glewGetProgramInfoLog = NULL;
PFNGLGETPROGRAMIVPROC __glewGetProgramiv = NULL;
PFNGLGETSHADERINFOLOGPROC __glewGetShaderInfoLog = NULL;
PFNGLGETSHADERSOURCEPROC __glewGetShaderSource = NULL;
PFNGLGETSHADERIVPROC __glewGetShaderiv = NULL;
PFNGLGETUNIFORMLOCATIONPROC __glewGetUniformLocation = NULL;
PFNGLGETUNIFORMFVPROC __glewGetUniformfv = NULL;
PFNGLGETUNIFORMIVPROC __glewGetUniformiv = NULL;
PFNGLGETVERTEXATTRIBPOINTERVPROC __glewGetVertexAttribPointerv = NULL;
PFNGLGETVERTEXATTRIBDVPROC __glewGetVertexAttribdv = NULL;
PFNGLGETVERTEXATTRIBFVPROC __glewGetVertexAttribfv = NULL;
PFNGLGETVERTEXATTRIBIVPROC __glewGetVertexAttribiv = NULL;
PFNGLISPROGRAMPROC __glewIsProgram = NULL;
PFNGLISSHADERPROC __glewIsShader = NULL;
PFNGLLINKPROGRAMPROC __glewLinkProgram = NULL;
PFNGLSHADERSOURCEPROC __glewShaderSource = NULL;
PFNGLSTENCILFUNCSEPARATEPROC __glewStencilFuncSeparate = NULL;
PFNGLSTENCILMASKSEPARATEPROC __glewStencilMaskSeparate = NULL;
PFNGLSTENCILOPSEPARATEPROC __glewStencilOpSeparate = NULL;
PFNGLUNIFORM1FPROC __glewUniform1f = NULL;
PFNGLUNIFORM1FVPROC __glewUniform1fv = NULL;
PFNGLUNIFORM1IPROC __glewUniform1i = NULL;
PFNGLUNIFORM1IVPROC __glewUniform1iv = NULL;
PFNGLUNIFORM2FPROC __glewUniform2f = NULL;
PFNGLUNIFORM2FVPROC __glewUniform2fv = NULL;
PFNGLUNIFORM2IPROC __glewUniform2i = NULL;
PFNGLUNIFORM2IVPROC __glewUniform2iv = NULL;
PFNGLUNIFORM3FPROC __glewUniform3f = NULL;
PFNGLUNIFORM3FVPROC __glewUniform3fv = NULL;
PFNGLUNIFORM3IPROC __glewUniform3i = NULL;
PFNGLUNIFORM3IVPROC __glewUniform3iv = NULL;
PFNGLUNIFORM4FPROC __glewUniform4f = NULL;
PFNGLUNIFORM4FVPROC __glewUniform4fv = NULL;
PFNGLUNIFORM4IPROC __glewUniform4i = NULL;
PFNGLUNIFORM4IVPROC __glewUniform4iv = NULL;
PFNGLUNIFORMMATRIX2FVPROC __glewUniformMatrix2fv = NULL;
PFNGLUNIFORMMATRIX3FVPROC __glewUniformMatrix3fv = NULL;
PFNGLUNIFORMMATRIX4FVPROC __glewUniformMatrix4fv = NULL;
PFNGLUSEPROGRAMPROC __glewUseProgram = NULL;
PFNGLVALIDATEPROGRAMPROC __glewValidateProgram = NULL;
PFNGLVERTEXATTRIBPOINTERPROC __glewVertexAttribPointer = NULL;

PFNGLBINDVERTEXARRAYPROC __glewBindVertexArray = NULL;
PFNGLDELETEVERTEXARRAYSPROC __glewDeleteVertexArrays = NULL;
PFNGLGENVERTEXARRAYSPROC __glewGenVertexArrays = NULL;
PFNGLISVERTEXARRAYPROC __glewIsVertexArray = NULL;
PFNGLACTIVETEXTUREPROC __glewActiveTexture = NULL;
PFNGLGENERATEMIPMAPPROC __glewGenerateMipmap = NULL;

}

#define DEF_FUNCPROC(x) \
	{ "gl" # x, (PROC *) &__glew ## x }

static const PROC_LIST my_gls[] = {
	DEF_FUNCPROC(ActiveTexture),
	DEF_FUNCPROC(GenVertexArrays),
	DEF_FUNCPROC(BindVertexArray),
	DEF_FUNCPROC(DeleteVertexArrays),
	DEF_FUNCPROC(GenBuffers),
	DEF_FUNCPROC(BindBuffer),
	DEF_FUNCPROC(BufferData),
	DEF_FUNCPROC(BufferSubData),
	DEF_FUNCPROC(DeleteBuffers),
	DEF_FUNCPROC(VertexAttribPointer),
	DEF_FUNCPROC(EnableVertexAttribArray),
	DEF_FUNCPROC(DisableVertexAttribArray),
	DEF_FUNCPROC(LinkProgram),
	DEF_FUNCPROC(ShaderSource),
	DEF_FUNCPROC(GetShaderiv),
	DEF_FUNCPROC(GetProgramiv),
	DEF_FUNCPROC(CompileShader),
	DEF_FUNCPROC(CreateProgram),
	DEF_FUNCPROC(CreateShader),
	DEF_FUNCPROC(DeleteProgram),
	DEF_FUNCPROC(DeleteShader),
	DEF_FUNCPROC(AttachShader),
	DEF_FUNCPROC(BindAttribLocation),
	DEF_FUNCPROC(GetAttribLocation),
	DEF_FUNCPROC(GetProgramInfoLog),
	DEF_FUNCPROC(GetShaderInfoLog),
	DEF_FUNCPROC(GetUniformLocation),
	DEF_FUNCPROC(UseProgram),
	DEF_FUNCPROC(Uniform1i),
	DEF_FUNCPROC(GenerateMipmap),
};


CGLUtil::CGLUtil()
{
}


CGLUtil::~CGLUtil()
{
}

void CGLUtil::init()
{
	TRACE(TEXT("GL Vendor    : %s\n"), glGetString(GL_VENDOR));
	TRACE(TEXT("GL Version   : %s\n"), glGetString(GL_VERSION));
	TRACE(TEXT("GLSL Version : %s\n"), glGetString(GL_SHADING_LANGUAGE_VERSION));

	for (int i = 0; i < ARRAY_SIZE(my_gls); ++i) {
		*my_gls[i].ppfunc = wglGetProcAddress(my_gls[i].funcname);
		TRACE(TEXT("[%d] Get '%s' addr = %p\n"), i + 1, my_gls[i].funcname, *my_gls[i].ppfunc);
	}
}
